import * as echarts from 'echarts'
import { Empty } from 'antd'
import { useEffect, useRef } from 'react'

type EChartsInitOpts = {
  readonly locale?: string
  readonly renderer?: 'canvas' | 'svg'
  readonly devicePixelRatio?: number
  readonly useDirtyRect?: boolean
  readonly width?: number
  readonly height?: number
}
type IProps = {
  readonly id: string
  readonly theme?: string | object | undefined
  readonly opts?: EChartsInitOpts
  readonly chartRef?: React.MutableRefObject<echarts.ECharts | undefined>
  readonly option: echarts.EChartsOption
  readonly className?: string
  readonly onEvents?: Record<string, Function>
  readonly onEvent?: { eventName: string; handler: () => boolean | void; context?: Object }
  readonly offEvent?: { eventName: string; handler: () => boolean | void }
  readonly height: number
  readonly display?: boolean
}

// --------------------------------------------------- 监听容器大小变化 ---------------------------------------------------
export const observeSizeChange = (ele: Element | null, callback: (entries: ResizeObserverEntry[], observer: ResizeObserver) => void) => {
  const re = new ResizeObserver(callback)
  re.disconnect() // 取消该元素上的所有监听
  if (ele) re.observe(ele) // 创建监听
}

export default function EchartsComponent({
  id,
  theme,
  opts,
  chartRef,
  option,
  onEvents,
  onEvent,
  offEvent,
  height,
  display = true,
  ...props
}: IProps) {
  const chartID = 'echarts-' + id
  const localChartRef = useRef<echarts.EChartsType>()
  const myChartRef = chartRef || localChartRef

  useEffect(() => {
    const renderChart = () => {
      myChartRef.current?.dispose()
      myChartRef.current = echarts.init(document.getElementById(chartID)!, theme, opts)
      myChartRef.current.setOption(option)
      if (onEvent) {
        myChartRef.current.on(onEvent.eventName, () => {
          onEvent.handler()
          if (onEvent.eventName === 'finished') myChartRef.current?.off(onEvent.eventName)
        })
      }
      myChartRef.current.resize({ animation: { duration: 300, easing: 'linear' } })
    }
    renderChart()
  }, [option, chartID, myChartRef, opts, theme, onEvent, offEvent])

  useEffect(() => {
    const ele = document.getElementById(chartID)
    const re = new ResizeObserver(() => myChartRef.current?.resize({ animation: { duration: 300, easing: 'linear' } }))
    re.disconnect() // 取消该元素上的所有监听
    if (ele) re.observe(ele) // 创建监听
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [chartID])

  return (
    <>
      <div id={chartID} style={{ height, display: display ? '' : 'none' }} {...props} />
      <Empty
        style={{ display: display ? 'none' : 'flex', justifyContent: 'center', flexDirection: 'column', height, margin: 0 }}
        image={Empty.PRESENTED_IMAGE_SIMPLE}
      />
    </>
  )
}
